package attendance

import (
	"fmt"
	"github.com/flipped-aurora/gin-vue-admin/server/global"
	"github.com/flipped-aurora/gin-vue-admin/server/model/attendance"
	attendanceReq "github.com/flipped-aurora/gin-vue-admin/server/model/attendance/request"
	"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
	"github.com/flipped-aurora/gin-vue-admin/server/service"
	"github.com/flipped-aurora/gin-vue-admin/server/utils"
	"github.com/gin-gonic/gin"
	"github.com/xuri/excelize/v2"
	"go.uber.org/zap"
	"strconv"
	"strings"
)

type StudentApi struct {
}

var stuService = service.ServiceGroupApp.AttendanceServiceGroup.StudentService
var fileUploadService = service.ServiceGroupApp.ExampleServiceGroup.FileUploadAndDownloadService

// CreateStudent 创建学生表
// @Tags Student
// @Summary 创建学生表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body attendance.Student true "创建学生表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /stu/createStudent [post]

func (stuApi *StudentApi) CreateStudent(c *gin.Context) {
	var stu attendance.Student
	err := c.ShouldBindJSON(&stu)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	stu.BelongTo = utils.GetBelongTo(c)
	if err := stuService.CreateStudent(&stu); err != nil {
		global.GVA_LOG.Error("创建失败!", zap.Error(err))
		response.FailWithMessage("创建失败", c)
	} else {
		fileUploadService.SavaPng(stu.StuNo, stu.Face)
		response.OkWithMessage("创建成功", c)
	}
}

func (stuApi *StudentApi) CreateStudentUpload(c *gin.Context) {
	file, _ := c.FormFile("file")
	if !strings.HasSuffix(file.Filename, ".xlsx") {
		response.FailWithMessage("请上传excel文件", c)
		return
	}
	src, err := file.Open()
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	defer src.Close()

	f, err := excelize.OpenReader(src)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	rows, err := f.GetRows("Sheet1")
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	for i, row := range rows {
		if i == 0 {
			continue
		}
		stu := attendance.Student{
			StuNo:    row[0],
			Class_id: row[1],
			Name:     row[2],
		}
		stu.BelongTo = utils.GetBelongTo(c)
		if err := stuService.CreateStudent(&stu); err != nil {
			global.GVA_LOG.Error("写入失败!", zap.Error(err))
			response.FailWithMessage(fmt.Sprintf("写入失败%s, err:%v", stu.StuNo, err), c)
			break
		}
	}
	response.OkWithMessage("上传成功", c)
}
func (stuApi *StudentApi) TemplateExport(c *gin.Context) {
	c.FileAttachment("uploads/templates/student.xlsx", "学生信息模板.xlsx")
}

// DeleteStudent 删除学生表
// @Tags Student
// @Summary 删除学生表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body attendance.Student true "删除学生表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /stu/deleteStudent [delete]
func (stuApi *StudentApi) DeleteStudent(c *gin.Context) {
	ID := c.Query("ID")
	if err := stuService.DeleteStudent(ID); err != nil {
		global.GVA_LOG.Error("删除失败!", zap.Error(err))
		response.FailWithMessage("删除失败", c)
	} else {
		fileUploadService.RemovePng(ID)
		response.OkWithMessage("删除成功", c)
	}
}

// DeleteStudentByIds 批量删除学生表
// @Tags Student
// @Summary 批量删除学生表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"批量删除成功"}"
// @Router /stu/deleteStudentByIds [delete]
func (stuApi *StudentApi) DeleteStudentByIds(c *gin.Context) {
	IDs := c.QueryArray("IDs[]")
	if err := stuService.DeleteStudentByIds(IDs); err != nil {
		global.GVA_LOG.Error("批量删除失败!", zap.Error(err))
		response.FailWithMessage("批量删除失败", c)
	} else {
		for _, id := range IDs {
			fileUploadService.RemovePng(id)
		}
		response.OkWithMessage("批量删除成功", c)
	}
}

// UpdateStudent 更新学生表
// @Tags Student
// @Summary 更新学生表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body attendance.Student true "更新学生表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /stu/updateStudent [put]
func (stuApi *StudentApi) UpdateStudent(c *gin.Context) {
	var stu attendance.Student
	err := c.ShouldBindJSON(&stu)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	fileUploadService.SavaPng(strconv.Itoa(int(stu.ID)), stu.Face)
	if err := stuService.UpdateStudent(stu); err != nil {
		global.GVA_LOG.Error("更新失败!", zap.Error(err))
		response.FailWithMessage("更新失败", c)
	} else {
		response.OkWithMessage("更新成功", c)
	}
}

// FindStudent 用id查询学生表
// @Tags Student
// @Summary 用id查询学生表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query attendance.Student true "用id查询学生表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /stu/findStudent [get]
func (stuApi *StudentApi) FindStudent(c *gin.Context) {
	ID := c.Query("ID")
	if restu, err := stuService.GetStudent(ID); err != nil {
		global.GVA_LOG.Error("查询失败!", zap.Error(err))
		response.FailWithMessage("查询失败", c)
	} else {
		restu.Face, _ = fileUploadService.ReadPng(ID)
		response.OkWithData(gin.H{"restu": restu}, c)
	}
}

// GetStudentList 分页获取学生表列表
// @Tags Student
// @Summary 分页获取学生表列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query attendanceReq.StudentSearch true "分页获取学生表列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /stu/getStudentList [get]
func (stuApi *StudentApi) GetStudentList(c *gin.Context) {
	var pageInfo attendanceReq.StudentSearch
	err := c.ShouldBindQuery(&pageInfo)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if list, total, err := stuService.GetStudentInfoList(pageInfo, utils.GetBelongTo(c)); err != nil {
		global.GVA_LOG.Error("获取失败!", zap.Error(err))
		response.FailWithMessage("获取失败", c)
	} else {
		for i, _ := range list {
			list[i].Face, _ = fileUploadService.ReadPng(strconv.Itoa(int(list[i].ID)))
		}
		response.OkWithDetailed(response.PageResult{
			List:     list,
			Total:    total,
			Page:     pageInfo.Page,
			PageSize: pageInfo.PageSize,
		}, "获取成功", c)
	}
}

// GetStudentPublic 不需要鉴权的学生表接口
// @Tags Student
// @Summary 不需要鉴权的学生表接口
// @accept application/json
// @Produce application/json
// @Param data query attendanceReq.StudentSearch true "分页获取学生表列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /stu/getStudentPublic [get]
func (stuApi *StudentApi) GetStudentPublic(c *gin.Context) {
	// 此接口不需要鉴权
	// 示例为返回了一个固定的消息接口，一般本接口用于C端服务，需要自己实现业务逻辑
	response.OkWithDetailed(gin.H{
		"info": "不需要鉴权的学生表接口信息",
	}, "获取成功", c)
}
